package org.dtp;

import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.boot.context.properties.bind.Bindable;
import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.ResolvableType;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotationMetadata;

/**
 * @author BestLee
 * @description 动态注册bean
 */
/* ImportBeanDefinitionRegistrar动态注册bean  可参考https://cloud.tencent.com/developer/article/2316949*/
/*EnvironmentAware 主要为了获取application.yml中的配置*/
public class DtpImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar, EnvironmentAware {
    private Environment environment;

    @Override
    public void setEnvironment(Environment environment) {
        this.environment = environment;
    }

    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry, BeanNameGenerator importBeanNameGenerator) {
        DtpProperties dtpProperties = new DtpProperties();
        /*Binder文章参考 https://www.jianshu.com/p/4feab6df384e*/
        Binder binder = Binder.get(environment);//绑定配置器
        /*ResolvableType文章参考 https://blog.csdn.net/zzuhkp/article/details/107749148*/
        ResolvableType resolvableType = ResolvableType.forClass(DtpProperties.class);
        Bindable<Object> bindable = Bindable.of(resolvableType).withExistingValue(dtpProperties);
        binder.bind("dtp", bindable);

        /*将线程池注册到容器中*/
        for (DtpProperties.DtpExecutorProperties executorProperties : dtpProperties.getExecutor()) {
            String poolName = executorProperties.getPoolName();
            AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
            beanDefinition.setBeanClass(DtpExecutor.class);
            beanDefinition.getConstructorArgumentValues().addGenericArgumentValue(executorProperties.getCorePoolSize());
            beanDefinition.getConstructorArgumentValues().addGenericArgumentValue(executorProperties.getMaximumPoolSize());
            registry.registerBeanDefinition(poolName, beanDefinition);
        }

    }
}
